flyui.namespace("flyui.flyatlas");


/**
 * @class
 * @extends flyui.sparql.Service
 */
flyui.flyatlas.Service = function() {};


// inherit
flyui.flyatlas.Service.prototype = new flyui.sparql.Service();


/**
 * @param {String} affyId
 * @param {Function} success will be passed an array of AssayGroup objects
 * @param {Function} failure
 */
flyui.flyatlas.Service.prototype.getAssaysByAffyProbeId = function( affyId, success, failure ) {
    flyui.info("flyui.flyatlas.Service :: getAssaysByProbeId request: "+affyId);
    var chain = flyui.chain(flyui.flyatlas.Service.responseToAssayGroups, success);
    var query = this._buildQueryForGetAssaysByProbeId(affyId);
    flyui.debug("query: "+query);
    this.postQuery(query, chain, failure);
};


flyui.flyatlas.Service.prototype.getAssaysByFlybaseGeneId = function( flybaseId, success, failure ) {
    flyui.info("flyui.flyatlas.Service :: getAssaysByGene request: "+flybaseId);
    var chain = flyui.chain(flyui.flyatlas.Service.responseToAssayGroups, success);
    var query = this._buildQueryForGetAssaysByFlybaseGeneId(flybaseId);
    flyui.debug("query: "+query);
    this.postQuery(query, chain, failure);
}


flyui.flyatlas.Service.responseToAssayGroups = function( response ) {
        
    flyui.debug("response status: "+response.status);
    
    // try parsing response text as json
    flyui.debug("parsing response as json: "+response.responseText);
    var resultSet = YAHOO.lang.JSON.parse(response.responseText);
    
    // convert result set to an array of genes
    var groups = flyui.flyatlas.AssayGroup.newInstancesFromResultSet(resultSet);
    
    return groups;
    
};


/**
 * @private
 * @param {String} query
 * @type String
 */
flyui.flyatlas.Service.prototype._buildQueryForGetAssaysByProbeId = function( affyId ) {

    var head =          "PREFIX xs: <http://www.w3.org/2001/XMLSchema#> \n" + 
                        "PREFIX : <http://purl.org/NET/flyatlas/schema#> ";
                
    var body_start =    "SELECT * WHERE { \n" +
                        "?probedata :affy_id \""+affyId+"\"^^xs:string , ?affy_id ; a :ProbeData ; \n" +
                        "  :fly_present ?whole_present ; \n" +
                        "  :fly_mean ?whole_mean ; \n" +
                        "  :fly_SEM ?whole_sem ; ";
    
    function body_part( tissue ) {
    	return          "  :"+tissue+" [ \n" + 
						"    a :TissueVals ; \n" +
						"    :t_change ?"+tissue+"_change ; \n" +
						"    :mean ?"+tissue+"_mean ; \n" +
						"    :sem ?"+tissue+"_sem ; \n" +
						"    :present ?"+tissue+"_present ; \n" +
						"    :ratio ?"+tissue+"_ratio ; \n" +
						"  ] ; "
    }

    var body_end =      " . }";
    
    var query = head;
    query += body_start;
    for (var i=0; i<flyui.flyatlas.tissues.length; i++) { 
        var tissue = flyui.flyatlas.tissues[i];
        if (tissue != "whole") {
            query += body_part(flyui.flyatlas.tissues[i]); 
        }
    }
    query += body_end;
    return query;

}

/**
 * @private
 * @param {String} query
 * @type String
 */
flyui.flyatlas.Service.prototype._buildQueryForGetAssaysByFlybaseGeneId = function( flybaseId ) {

    var head =          "PREFIX xs: <http://www.w3.org/2001/XMLSchema#> \n" + 
                        "PREFIX : <http://purl.org/NET/flyatlas/schema#> \n" +
                        "PREFIX fb: <http://openflydata.org/id/flybase/feature/> \n";
                
    var body_start =    "SELECT * WHERE { \n" +
                        "?probedata :gene fb:"+flybaseId+"; \n" +
                        "  a :ProbeData ; \n" +
                        "  :affy_id ?affy_id ; \n" +
                        "  :fly_present ?whole_present ; \n" +
                        "  :fly_mean ?whole_mean ; \n" +
                        "  :fly_SEM ?whole_sem ; \n";
    
    function body_part( tissue ) {
    	return          "  :"+tissue+" [ \n" + 
						"    a :TissueVals ; \n" +
						"    :t_change ?"+tissue+"_change ; \n" +
						"    :mean ?"+tissue+"_mean ; \n" +
						"    :sem ?"+tissue+"_sem ; \n" +
						"    :present ?"+tissue+"_present ; \n" +
						"    :ratio ?"+tissue+"_ratio ; \n" +
						"  ] ; \n"
    }

    var body_end =      " . }";
    
    var query = head;
    query += body_start;
    for (var i=0; i<flyui.flyatlas.tissues.length; i++) { 
        var tissue = flyui.flyatlas.tissues[i];
        if (tissue != "whole") {
            query += body_part(flyui.flyatlas.tissues[i]); 
        }
    }
    query += body_end;
    return query;

}


/**
 * @class
 */
flyui.flyatlas.AssayGroup = function() {};

/**
 * @type String
 */
flyui.flyatlas.AssayGroup.prototype.affy_id = null;

/**
 * @type flyui.flyatlas.Assay
 */
flyui.flyatlas.AssayGroup.prototype.whole = null;

/**
 * @type flyui.flyatlas.Assay
 */
flyui.flyatlas.AssayGroup.prototype.brain = null;

/**
 * @type flyui.flyatlas.Assay
 */
flyui.flyatlas.AssayGroup.prototype.head = null;

/**
 * @type flyui.flyatlas.Assay
 */
flyui.flyatlas.AssayGroup.prototype.crop = null;

/**
 * @type flyui.flyatlas.Assay
 */
flyui.flyatlas.AssayGroup.prototype.midgut = null;

/**
 * @type flyui.flyatlas.Assay
 */
flyui.flyatlas.AssayGroup.prototype.hindgut = null;

/**
 * @type flyui.flyatlas.Assay
 */
flyui.flyatlas.AssayGroup.prototype.tubule = null;

/**
 * @type flyui.flyatlas.Assay
 */
flyui.flyatlas.AssayGroup.prototype.ovary = null;

/**
 * @type flyui.flyatlas.Assay
 */
flyui.flyatlas.AssayGroup.prototype.testis = null;

/**
 * @type flyui.flyatlas.Assay
 */
flyui.flyatlas.AssayGroup.prototype.acc = null;

/**
 * @type flyui.flyatlas.Assay
 */
flyui.flyatlas.AssayGroup.prototype.l_tubule = null;

/**
 * @type flyui.flyatlas.Assay
 */
flyui.flyatlas.AssayGroup.prototype.l_fatbody = null;

/**
 * @type flyui.flyatlas.Assay
 */
flyui.flyatlas.AssayGroup.prototype.ta_ganglion = null;

/**
 * @type flyui.flyatlas.Assay
 */
flyui.flyatlas.AssayGroup.prototype.carcass = null;

/**
 * @type flyui.flyatlas.Assay
 */
flyui.flyatlas.AssayGroup.prototype.sgland = null;


/**
 * @param {Object} resultSet
 * @type Array<flyui.flyatlas.AssayGroup>
 */
flyui.flyatlas.AssayGroup.newInstancesFromResultSet = function( resultSet ) {
	var groups = [];
	for (var i=0; i<resultSet.results.bindings.length; i++) {
		var binding = resultSet.results.bindings[i];
		groups[groups.length] = flyui.flyatlas.AssayGroup.newInstanceFromBinding(binding);
	}
	return groups;
};


/**
 * @param {Object} binding
 * @type flyui.flyatlas.AssayGroup
 */
flyui.flyatlas.AssayGroup.newInstanceFromBinding = function( binding ) {
	var group = new flyui.flyatlas.AssayGroup();
	
	group.affy_id = binding["affy_id"].value;
	
	// populate assays
	for (var i=0; i<flyui.flyatlas.tissues.length; i++) {
		var tissue = flyui.flyatlas.tissues[i];
		group[tissue] = flyui.flyatlas.Assay.newInstanceFromBinding(binding, tissue);
	}
	
    return group;	
};


/**
 * @class
 */
flyui.flyatlas.Assay = function() {};

/**
 * @type Number
 */
flyui.flyatlas.Assay.prototype.mean = null;

/**
 * @type Number
 */
flyui.flyatlas.Assay.prototype.present = null;

/**
 * @type Number
 */
flyui.flyatlas.Assay.prototype.sem = null;

/**
 * @type String
 */
flyui.flyatlas.Assay.prototype.change = null;

/**
 * @type Number
 */
flyui.flyatlas.Assay.prototype.ratio = null;


/**
 * @param {Object} binding
 * @param {String} tissue
 * @type flyui.flyatlas.Assay
 */
flyui.flyatlas.Assay.newInstanceFromBinding = function( binding, tissue ) {
	var assay = new flyui.flyatlas.Assay();
	
	var sharedProps = ["mean", "sem", "present"];
	
	// populate shared props
	for (var i=0; i<sharedProps.length; i++) {
		var p = sharedProps[i];
		assay[p] = binding[tissue+"_"+p].value;
	}

    var otherProps = ["ratio", "change"];
    
    if (tissue == "whole") {
    	// force prop values for whole fly
        assay.ratio = 1;
        assay.change = "None";    	
    }
    else {
	    for (var i=0; i<otherProps.length; i++) {
	        var op = otherProps[i];
	        if (binding[tissue+"_"+op]) {
	            assay[op] = binding[tissue+"_"+op].value;
	        }
	    }
    }

    return assay;
    	
};


/**
 * @type Array
 */
flyui.flyatlas.tissues = [
    "whole",
    "brain",
    "head",
    "crop",
    "midgut",
    "hindgut",
    "tubule",
    "ovary",
    "testis",
    "acc",
    "l_tubule",
    "l_fatbody",
    "ta_ganglion",
    "carcass",
    "sgland"
];
